package com.smart.service.impl;

import java.util.Map;
import java.util.List;
import java.util.Arrays;
import java.util.HashMap;
import com.smart.vo.AppUserVo;
import com.smart.entity.SysCar;
import com.smart.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import com.smart.mapper.UserMapper;
import cn.hutool.core.util.StrUtil;
import com.smart.service.CarService;
import com.smart.service.UserService;
import com.smart.service.RoleService;
import com.smart.service.OnlineUserService;
import com.smart.common.component.JwtTokenUtil;
import com.smart.common.util.SecurityUtils;
import com.smart.common.util.SysUserUtils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.security.core.userdetails.UserDetails;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

/**
 * @author lgb
 * @date 2020年6月9日 上午11:36:47
 * Copyright (C) 深圳工勘科技
 * @说明: 用户管理
 **/
@Slf4j
@Service("sysUserService")
public class UserServiceImpl extends BaseServiceImpl<SysUser,Long> implements UserService{

	@Resource
	private UserMapper userMapper;
	@Resource
	private UserService userService;
	@Resource
	private RoleService roleService;
	@Resource
	private JwtTokenUtil jwtTokenUtil;
	@Resource
	private PasswordEncoder passwordEncoder;
	@Resource
	private OnlineUserService onlineUserService;
	@Resource
	private UserDetailsService userDetailsService;
	@Resource
	private CarService carService;
	/** 
	 * (non-Javadoc)
	 * @see: 
	 **/
	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public AppUserVo login(String un,String pwd,HttpServletRequest req){
		AppUserVo vo = verUserDetails(un,pwd,req);
		// 密码需要客户端加密后传递
		boolean singleLogin = false;
		if (singleLogin) {//踢掉之前已经登录的token
			SysUser details = SysUserUtils.getSysUser();
			onlineUserService.checkLoginOnUser(details.getUsername(),vo.getToken());
		}
		return vo;
	}

	@Override
	@Transactional(readOnly=true)
	public AppUserVo appLogin(String un,String pwd,HttpServletRequest req){
		return verUserDetails(un,pwd,req);
	}

	/** 
	 * (non-Javadoc)
	 * @see: 根据用户名获取用户
	 **/
	@Override
	@Transactional(readOnly=true)
	public SysUser getByUserName(String username) {
		return this.baseMapper.selectOne(
		new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
	}
	
	/**
	 * @param un 用户名
	 * @param pwd 密码
	 * @return 根据用户名与密码验证用户详情
	 **/
	private AppUserVo verUserDetails(String un,String pwd,HttpServletRequest req) {
		AppUserVo vo = new AppUserVo();
		UserDetails userDetails = userDetailsService.loadUserByUsername(un);
		if (!passwordEncoder.matches(pwd, userDetails.getPassword())) {
			throw new BadCredentialsException("密码不正确");
		}
		UsernamePasswordAuthenticationToken authentication = 
				new UsernamePasswordAuthenticationToken(userDetails,null,
				userDetails.getAuthorities());
		SecurityContextHolder.getContext().setAuthentication(authentication);
		String token = jwtTokenUtil.generateToken(userDetails.getUsername());
		SysUser details = SysUserUtils.getSysUser();
		try {
			BeanUtils.copyProperties(vo,details);
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
			log.warn("登录异常:{}",e.getMessage());
		}
		vo.setToken(token);
		vo.setTokenHead(jwtTokenUtil.getTokenHead());
        vo.setExpiration(jwtTokenUtil.getExpiration());
        Map<String,Object> roleData = new HashMap<String,Object>();
        roleData.put("roleId",details.getRoleId());
        roleData.put("roleName",details.getRoleName());
        vo.setSysRole(roleData);
        /** 查询当前用户的车辆情况(包括设备信息) */
        Map<String,Object> car = carService.getCarListByUserId(details.getId());
        vo.setSysCar(car);
        /** 用户信息 */
        vo.setSysUser(details);
        return vo;
	}

	/** 
	 * (non-Javadoc)
	 * @see: 修改密码
	 **/
	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public int updatePasswordByUserId(Long userId,String newPassword) {
		SysUser user = new SysUser();
        user.setPassword(newPassword);
        user.setId(userId);
        return this.baseMapper.updateById(user);
	}

	@Override
	@Transactional(readOnly=true)
	public IPage<SysUser> getPage(Map<String, Object> params) {
		SysUser sysUser = SysUserUtils.getSysUser();
		int pageSize = Integer.parseInt(String.valueOf(params.get("pageSize")));
        int pageNum = Integer.parseInt(String.valueOf(params.get("pageNum")));
        String username = (String) params.get("username");
        String phone = (String) params.get("phone");
        String deptId = (String) params.get("deptId");
        String beginTime = (String) params.get("beginTime");
        String endTime = (String) params.get("endTime");
        String status = (String) params.get("status");
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(username)) {
            wrapper.like(SysUser::getUsername, username);
        }
        if (StrUtil.isNotEmpty(phone)) {
            wrapper.like(SysUser::getPhone, phone);
        }
        if (StrUtil.isNotEmpty(deptId)) {
            wrapper.apply("(dept_id = " + deptId + " OR dept_id IN ( SELECT t.id FROM sys_dept t WHERE FIND_IN_SET ( " + deptId + " , ancestors ) ))");
        }
        if (StrUtil.isNotEmpty(beginTime)) {
            wrapper.gt(SysUser::getCreateTime,beginTime);
        }
        if (StrUtil.isNotEmpty(endTime)) {
            wrapper.lt(SysUser::getCreateTime, endTime);
        }
        if (StrUtil.isNotEmpty(status)) {
            wrapper.eq(SysUser::getStatus, status);
        }
        if(SecurityUtils.isAdmin(sysUser.getId())){
        	wrapper.notIn(SysUser::getId,1);
        }else{
        	wrapper.notIn(SysUser::getId,1,sysUser.getId()); 
        }
      
        wrapper.apply(params.get("sql_filter") != null, (String) params.get("sql_filter"));
        return page(new Page<>(pageNum, pageSize), wrapper);
	}

	/** 
	 * (non-Javadoc)
	 * @see: 创建用户及权限
	 **/
	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public int insertUserAndRole(SysUser user,String carNo) {
		List<Long> roleIds = null;// user.getRoleIds();
		user.setRoleId(roleIds.get(0));
		user.setRoleName(roleService.findById(roleIds.get(0)).getName());
		int result = this.baseMapper.insert(user);
		if(roleIds.get(0).intValue()== 3){//表示司机
		    List<SysCar> carList = carService.findCarByNo(carNo);
	    	if(carList.isEmpty()){
	    		
	    	}
		}
        //保存用户与角色关系
		//userMapper.insertUserAndUserRole(user.getId(),user.getRoleIds());
        return result;
	}

	@Override
	public int deleteByIds(Long[] ids) {
		 return this.baseMapper.deleteBatchIds(Arrays.asList(ids));
	}
	
	
	
	
}